import { validatenull } from './validate';
import CryptoJS from './crypto-js';

/**
 * 加密处理
 */
export const encryption = (params) => {
    let {
        data,
        type,
        param,
        key
    } = params;
    const result = JSON.parse(JSON.stringify(data));
    if (type === 'Base64') {
        param.forEach(ele => {
            result[ele] = btoa(result[ele]);
        });
    } else {
        param.forEach(ele => {
            const data = result[ele];
            key = CryptoJS.enc.Latin1.parse(key);
            const iv = key;
            // 加密
            const encrypted = CryptoJS.AES.encrypt(
                data,
                key,
                {
                    iv,
                    mode: CryptoJS.mode.CBC,
                    padding: CryptoJS.pad.ZeroPadding
                });
            result[ele] = encrypted.toString();
        });
    }
    return result;
};



/**
 * 时间日期格式化
 */
export const dateTimeFormatter = function (date, format) {
    // 时间格式化辅助函数 date:毫秒数(number类型) format:'yyyy-MM-dd hh:mm:ss'
    // toUTCString() 方法可根据世界时 (UTC) 把 Date 对象转换为字符串，并返回结果。
    if (!date || date == '' || date.toUTCString() == 'Invalid Date') {
        return '';
    }
    date = new Date(date);
    const map = {
        'M': date.getMonth() + 1, // 月份
        'd': date.getDate(), // 日
        'h': date.getHours(), // 小时
        'm': date.getMinutes(), // 分
        's': date.getSeconds(), // 秒
        'q': Math.floor((date.getMonth() + 3) / 3), // 季度
        'S': date.getMilliseconds() // 毫秒
    };
    format = format.replace(/([yMdhmsqS])+/g, (all, t) => {
        let v = map[t];
        if (v !== undefined) {
            if (all.length > 1) {
                v = '0' + v;
                v = v.substr(v.length - 2);
            }
            return v;
        } else if (t === 'y') {
            return (date.getFullYear() + '').substr(4 - all.length);
        }
        return all;
    });
    return format;
};


/**
 * 精度加减乘除
 */
export function floatAdd (_this, arg) {
    let r1,
        r2,
        m;
    try { r1 = _this.toString().split('.')[1].length; } catch (e) { r1 = 0; }
    try { r2 = arg.toString().split('.')[1].length; } catch (e) { r2 = 0; }
    m = Math.pow(10, Math.max(r1, r2));
    return ((_this * m + arg * m) / m).toString();
}
export function floatSub (_this, arg) {
    let r1,
        r2,
        m,
        n;
    try { r1 = _this.toString().split('.')[1].length; } catch (e) { r1 = 0; }
    try { r2 = arg.toString().split('.')[1].length; } catch (e) { r2 = 0; }
    m = Math.pow(10, Math.max(r1, r2));
    // 动态控制精度长度
    n = (r1 >= r2) ? r1 : r2;
    return ((_this * m - arg * m) / m).toFixed(n);
}
export function floatMul (_this, arg) {
    let m = 0,
        s1 = _this.toString(),
        s2 = arg.toString();
    try { m += s1.split('.')[1].length; } catch (e) { }
    try { m += s2.split('.')[1].length; } catch (e) { }
    return (Number(s1.replace('.', '')) * Number(s2.replace('.', '')) / Math.pow(10, m)).toString();
}
export function floatDiv (_this, arg) {
    let t1 = 0,
        t2 = 0,
        r1,
        r2;
    try { t1 = _this.toString().split('.')[1].length; } catch (e) { }
    try { t2 = arg.toString().split('.')[1].length; } catch (e) { }
    try { r1 = Number(_this.toString().replace('.', '')); } catch (e) { r1 = 0; }
    try { r2 = Number(arg.toString().replace('.', '')); } catch (e) { r2 = 0; }

    return floatMul((r1 / r2), Math.pow(10, t2 - t1));
}

/**
 * 数组去重 property obj属性
 */
export function arrayDuplicateRemoval (array, property) {
    const tempArray = new Array();
    const hasObj = new Object();
    if (array.length > 0) {
        if (typeof (array[1]) === 'object') {
            for (let i = 0; i < array.length; i++) {
                if (!hasObj[array[i][property]]) {
                    hasObj[array[i][property]] = 1;
                    tempArray.push(array[i]);
                }
            }
        } else {
            for (let i = 0; i < array.length; i++) {
                if (tempArray.indexOf(array[i]) < 0) {
                    tempArray.push(array[i]);
                }
            }
        }
        return tempArray;
    } else {
        return array;
    }
}


/*
 * 数组扁平化
 * @param arr 多维数组  children 默认参数
 * @returns 一维数组
 */
export function flatten (arr, children = 'children') {
    let result = []
    if (Array.isArray(arr)) {
        for (let item of arr) {
            if (item[children]?.length) {
                const item2 = JSON.parse(JSON.stringify(item))
                delete item2[children]
                result.push(item2)
                result = result.concat(flatten(item[children]))
            } else {
                result.push(item)
            }
        }
    }
    return result
}


/**
 * obj转 =  
 * {a:1,b:2} => a=1; b=2
 */
export const objToFilter = o => {
    const str = [];
    for (const p in o) {
        if (!validatenull(o[p])) {
            str.push(p + '=' + o[p]);
        }
    }
    return str.join(';');
};

/**
 * obj 属性置空
 */
export const resetObjNull = o => {
    for (const p in o) {
        if (o[p] instanceof Array) {
            o[p] = [];
        } else {
            o[p] = null;
        }
    }
};


/**
 * 导出 excel
 * @param {*} data 要导出的数据
 * @param {*} fileName 文件名
 */
export function exportExcel (data, fileName) {
    const blob = new Blob([data], {
        type: 'application/vnd.ms-excel'
    });
    if ('download' in document.createElement('a')) { // 非IE下载
        const elink = document.createElement('a');
        elink.download = fileName;
        elink.style.display = 'none';
        elink.href = URL.createObjectURL(blob);
        document.body.appendChild(elink);
        elink.click();
        URL.revokeObjectURL(elink.href); // 释放URL 对象
        document.body.removeChild(elink);
    } else { // IE10+下载
        navigator.msSaveBlob(blob, fileName);
    }
}


/**
 * 导出 pdf
 * @param {*} data 要导出的数据
 * @param {*} fileName 文件名
 */
export function exportPDF (data, fileName) {
    const blob = new Blob([data], {
        type: 'application/pdf;chartset=UTF-8'
    });
    if ('download' in document.createElement('a')) { // 非IE下载
        const elink = document.createElement('a');
        elink.download = fileName;
        elink.style.display = 'none';
        elink.action = '#';
        elink.href = URL.createObjectURL(blob);
        document.body.appendChild(elink);
        elink.click();
        URL.revokeObjectURL(elink.href); // 释放URL 对象
        document.body.removeChild(elink);
    } else { // IE10+下载
        navigator.msSaveBlob(blob, fileName);
    }
}

/**
 * 深拷贝
 */
export function deepClone (source) {
    if (!source && typeof source !== 'object') {
        throw new Error('error arguments', 'deepClone')
    }
    const targetObj = source.constructor === Array ? [] : {}
    Object.keys(source).forEach(keys => {
        if (source[keys] && typeof source[keys] === 'object') {
            targetObj[keys] = deepClone(source[keys])
        } else {
            targetObj[keys] = source[keys]
        }
    })
    return targetObj
}


/**
 * 函数防抖 (只执行最后一次点击 输入框输入搜索 window窗口resize)
 */
export const debounce = (fn, t) => {
    let delay = t || 500;
    let timer;
    return function () {
        let args = arguments;
        if (timer) {
            clearTimeout(timer);
        }
        timer = setTimeout(() => {
            timer = null;
            fn.apply(this, args);
        }, delay);
    }
};


/**
 * 函数节流 (规定时间内只执行一次 监听滚动事件 滑动底部加载更多)
 */
export const throttle = (fn, t) => {
    let last;
    let timer;
    let interval = t || 500;
    return function () {
        let args = arguments;
        let now = +new Date();
        if (last && now - last < interval) {
            clearTimeout(timer);
            timer = setTimeout(() => {
                last = now;
                fn.apply(this, args);
            }, interval);
        } else {
            last = now;
            fn.apply(this, args);
        }
    }
};


/**
 * 获取url参数
 */
export function getQueryObject (url) {
    url = window.location.href
    const search = url.substring(url.lastIndexOf('?') + 1)
    const obj = {}
    const reg = /([^?&=]+)=([^?&=]*)/g
    search.replace(reg, (rs, $1, $2) => {
        const name = decodeURIComponent($1)
        let val = decodeURIComponent($2)
        val = String(val)
        obj[name] = val
        return rs
    })
    return obj
}



//阻止冒泡
export function stopBubble (e) {
    //如果提供了事件对象，则这是一个非IE浏览器
    if (e && e.stopPropagation) {
        //因此它支持W3C的stopPropagation()方法
        e.stopPropagation();
    }
    else {
        //否则，我们需要使用IE的方式来取消事件冒泡
        window.event.cancelBubble = true;
    }
}

//阻止浏览器的默认行为
export function stopDefault (e) {
    //防止浏览器默认行为(W3C)
    if (e && e.preventDefault) {
        e.preventDefault();
    }
    //IE中组织浏览器行为
    else {
        window.event.returnValue = false;
        return false;
    }
}


// 手机号脱敏
export function hiddenPhone (telephone) {
    telephone += ''; //转为字符串
    if (!validatenull(telephone)) {
        const prefix = telephone.slice(0, 3);
        const suffix = telephone.slice(7, 11);
        return prefix + '****' + suffix;
    } else {
        return "";
    }
}

// 获取浏览器类型
export function getBrowerType () {
    var ua = navigator.userAgent;
    let tname = '';

    if (/firefox/i.test(ua)) {
        tname = 'firefox'
    } else if (/chrome/i.test(ua)) {
        tname = 'chrome'
    } else if (/mise/i.test(ua)) {
        tname = 'IE'
    } else if ("ActiveXObject" in window) {
        tname = 'IE'
    }
}

// 自定义判断元素类型
function toType(obj) {
    return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}
// 参数过滤函数
export function filterNull (o) {
    for (let key in o) {
        if (o[key] === null) {
            delete o[key]
        }
        if (toType(o[key]) === 'string') {
            o[key] = o[key].trim()
        } else if (toType(o[key]) === 'object') {
            o[key] = filterNull(o[key])
        } else if (toType(o[key]) === 'array') {
            o[key] = filterNull(o[key])
        }
    }
    return o
}